package com.ruoyi.crm.service.impl;

import java.util.List;
import java.util.stream.Collectors;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.crm.async.ClueRecordAsync;
import com.ruoyi.crm.domain.AssignRecord;
import com.ruoyi.crm.domain.Business;
import com.ruoyi.crm.domain.CrmUser;
import com.ruoyi.crm.domain.vo.*;
import com.ruoyi.crm.enums.StatusType;
import com.ruoyi.crm.mapper.AssignRecordMapper;
import com.ruoyi.crm.mapper.BusinessMapper;
import com.ruoyi.crm.service.CrmUserService;
import com.ruoyi.crm.service.ICourseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import com.ruoyi.crm.mapper.ClueMapper;
import com.ruoyi.crm.domain.Clue;
import com.ruoyi.crm.service.IClueService;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;

/**
 * 线索管理Service业务层处理
 * @author ruoyi
 * @date 2022-06-07
 */
@Slf4j
@Service
@Transactional
public class ClueServiceImpl implements IClueService {
	@Resource
	private ClueMapper clueMapper;
	@Resource
	private AssignRecordMapper assignRecordMapper;
	@Resource
	private MongoTemplate mongoTemplate;
	/* 异步任务：新增线索记录，用于捞取线索 */
	@Resource
	private ClueRecordAsync clueRecordAsync;
	@Resource
	private BusinessMapper businessMapper;
	@Autowired
	private CrmUserService crmUserService;
	@Resource
	private ICourseService icourseService;

	/**
	 * 查询线索管理
	 *
	 * @param id 线索管理主键
	 * @return 线索管理
	 */
	@Override
	public ClueVO selectClueById(Long id) {
		return clueMapper.selectClueById(id.toString());
	}

	/**
	 * 查询线索管理列表
	 *
	 * @param clue 线索管理
	 * @return 线索管理
	 */
	@Override
	public List<Clue> selectClueList(Clue clue) {
		clue.setUserName(SecurityUtils.getUsername());
		return clueMapper.selectClueList(clue);
	}

	/**
	 * 新增线索管理
	 * 需要向分配表中新增一条分配线索记录
	 * @param clue 线索管理
	 * @return 结果
	 */
	@Override
	public int insertClue(Clue clue) {
		String username = SecurityUtils.getUsername();
		clue.setCreateTime(DateUtils.getNowDate());
		clue.setCreateBy(username);
		//新增线索为待跟进状态
		clue.setStatus(StatusType.UNFOLLOWED.getValue());
		clueMapper.insertClue(clue);

		//需要想分配表中添加数据
		AssignRecord record = new AssignRecord();
		record.setCreateTime(DateUtils.getNowDate());
		record.setAssignId(clue.getId());
		record.setCreateBy(username);
		record.setUserName(username);
		//获取所属人部分
		LoginUser loginUser = SecurityUtils.getLoginUser();
		record.setDeptId(loginUser.getDeptId());
		record.setUserId(loginUser.getUserId());
		return assignRecordMapper.insertAssignRecord(record);
	}

	/**
	 * 修改线索管理
	 * @param clue 线索管理
	 * @return 结果
	 */
	@Override
	public int updateClue(Clue clue) {
		clue.setUpdateTime(DateUtils.getNowDate());
		return clueMapper.updateClue(clue);
	}

	/**
	 * 批量删除线索管理
	 *
	 * @param ids 需要删除的线索管理主键
	 * @return 结果
	 */
	@Override
	public int deleteClueByIds(Long[] ids) {
		return clueMapper.deleteClueByIds(ids);
	}

	/**
	 * 删除线索管理信息
	 * @param id 线索管理主键
	 * @return 结果
	 */
	@Override
	public int deleteClueById(Long id) {
		return clueMapper.deleteClueById(id);
	}

	/**
	 * 转伪线索
	 * 1、修改线索状态：4
	 * 2、将线索的数据存储在Mongodb
	 * @param clueId
	 * @param falseClueVO
	 * @return
	 */
	@Override
	public AjaxResult clueFalse(Long clueId, FalseClueVO falseClueVO) {
		ClueVO clueVO = this.selectClueById(clueId);
		Clue clue = new Clue();
		clue.setId(clueId);
		clue.setStatus(StatusType.FALSE.getValue());
		clue.setFalseCount(clueVO.getFalseCount()+1);
		clueMapper.updateClue(clue);

		MongoClueRecordVO mongoClueRecordVO = new MongoClueRecordVO();
		mongoClueRecordVO.setClueId(clueId.intValue());
		falseClueVOToMongoClueRecord(falseClueVO,mongoClueRecordVO);
		mongoTemplate.save(mongoClueRecordVO);
		return AjaxResult.success();
	}

	public void falseClueVOToMongoClueRecord(FalseClueVO fc,MongoClueRecordVO mc) {
		BeanUtils.copyProperties(fc,mc);
		mc.setFalseReason(fc.getReason());
		mc.setRecord(mc.getRemark());
		mc.setRemark(null);
		mc.setCreateBy(SecurityUtils.getUsername());
		mc.setType(MongoClueRecordVO.StatusType.FLASE_CLUE.getVal());
		mc.setCreateTime(DateUtils.getNowDate());
	}

	/**
	 * 线索池：伪线索
	 * @param clue
	 * @return
	 */
	@Override
	public List<CluePoolVO> selectFalseClueList(Clue clue) {
		clue.setUserName(SecurityUtils.getUsername());
		return clueMapper.selectFalseClueList(clue);
 	}

	/**
	 * 捞取线索
	 * @param clueGainVO
	 */
	@Override
	public void gain(ResourceGainVO clueGainVO) {
		//1、修改线索状态为1
		clueMapper.gainClue(clueGainVO.getIds());
		//2、修改最新分配人为 0
		assignRecordMapper.gainNewAssigner(clueGainVO.getIds());
		//3、新增线索记录：异步任务
		clueRecordAsync.executeClueRecord(clueGainVO,SecurityUtils.getLoginUser());
	}

	/**
	 * 转商机：
	 * 1、删除MongoDB中线索操作记录的数据
	 * 2、将线索信息转为商机，修改线索状态：6
	 * 3、向分配表中插入转商机的记录
	 * @param clueId
	 */
	@Override
	public void changeBusiness(Long clueId) {
		Query query = new Query(Criteria.where("clueId").is(clueId));
		mongoTemplate.remove(query,MongoClueRecordVO.class);

		ClueVO clueVO = this.selectClueById(clueId);
		clueVO.setStatus(StatusType.TOBUSINESS.getValue());
		clueMapper.updateClueTOBusinessStatus(clueVO);

		Business business = this.clueToBusiness(clueVO);
		businessMapper.insertBusiness(business);
		assignRecordMapper.insertAssignRecord(buildAssignRecord(business.getId().longValue()));
	}

	/**
	 * 线索分配
	 * 1、将前分配记录表的线索 状态改为 0
	 * 2、将线索的状态改为 已分配（1），并且将transfer改为1
	 * 3、将分配用户的信息查询出来，新增新分配的线索，并且状态：1
	 * 4、向分配记录表新增一条线索记录
	 * @param clueGainVO
	 * @return
	 */
	@Override
	public AjaxResult assignment(ResourceGainVO clueGainVO) {
		log.info("ClueServiceImpl.assignment.clueGainVO入参：{}",clueGainVO);
		clueMapper.AssignmentClue(clueGainVO.getIds());

		CrmUser crmUser = crmUserService.queryById(clueGainVO.getUserId().longValue());
		List<Clue> clues = clueMapper.selectClueByIdList(clueGainVO.getIds());

		List<Long> clueId = clues.stream().
				map(c -> c.getId()).collect(Collectors.toList());
		//modify clues latest
		assignRecordMapper.updateClueLatest(clueId);

		LoginUser loginUser = SecurityUtils.getLoginUser();
		clues.forEach(c -> {
			 c.setStatus(StatusType.UNFOLLOWED.getValue());
			 c.setCreateBy(crmUser.getUserName());
			 c.setTransfer("0");
			clueMapper.insertClue(c);

			//新增新分配人的线索
			AssignRecord record = new AssignRecord();
			record.setDeptId(crmUser.getDeptId());
			record.setLatest("1");
			record.setUserName(crmUser.getUserName());
			record.setCreateBy(loginUser.getUsername());
			record.setUserId(crmUser.getUserId());
			record.setAssignId(c.getId());
			record.setType("0");
			record.setCreateTime(DateUtils.getNowDate());
			assignRecordMapper.insertAssignRecord(record);
		});
		return AjaxResult.success("线索分配成功");
	}

	@Override
	public AjaxResult courseListselect(String subject) {
		return AjaxResult.success(icourseService.courseListBySubject(subject));
	}

	public Business clueToBusiness(ClueVO clueVO){
		Business business = new Business();
		BeanUtils.copyProperties(clueVO, business);
		business.setClueId(clueVO.getId());
		business.setStatus(StatusType.UNFOLLOWED.getValue());
		return business;
	}

	public AssignRecord buildAssignRecord(Long businessId){
		LoginUser loginUser = SecurityUtils.getLoginUser();

		AssignRecord assignRecord = new AssignRecord();
		assignRecord.setType("1");
		assignRecord.setLatest("1");
		assignRecord.setAssignId(businessId);
		assignRecord.setUserName(loginUser.getUsername());
		assignRecord.setCreateBy(loginUser.getUsername());
		assignRecord.setUserId(loginUser.getUserId());
		assignRecord.setDeptId(loginUser.getDeptId());
		assignRecord.setCreateTime(DateUtils.getNowDate());
		return assignRecord;
	}
}
